package com.study.netty.udp.simple;

import io.grpc.netty.shaded.io.netty.bootstrap.Bootstrap;
import io.grpc.netty.shaded.io.netty.buffer.ByteBuf;
import io.grpc.netty.shaded.io.netty.channel.Channel;
import io.grpc.netty.shaded.io.netty.channel.ChannelHandlerContext;
import io.grpc.netty.shaded.io.netty.channel.ChannelInitializer;
import io.grpc.netty.shaded.io.netty.channel.ChannelOption;
import io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoopGroup;
import io.grpc.netty.shaded.io.netty.channel.socket.DatagramPacket;
import io.grpc.netty.shaded.io.netty.channel.socket.nio.NioDatagramChannel;
import io.grpc.netty.shaded.io.netty.handler.codec.MessageToMessageDecoder;
import io.grpc.netty.shaded.io.netty.util.CharsetUtil;

import java.util.List;

/**
 * @author ysy
 * @version 1.0
 * @Title: UdpReciever
 * @Note <b>ProjectName:</b> Pre-research
 * <br><b>PackageName:</b> com.study.netty.udp
 * <br><b>ClassName:</b>
 * <br><b>Date:</b>

 */
public class UdpReciever {

    // 监听端口
    private static final int RECEIVE_PORT = 8081;

    /**
     * NioSocketChannel, 代表异步的客户端 TCP Socket 连接.
     * NioServerSocketChannel, 异步的服务器端 TCP Socket 连接.
     * NioDatagramChannel, 异步的 UDP 连接
     * NioSctpChannel, 异步的客户端 Sctp 连接.
     * NioSctpServerChannel, 异步的 Sctp 服务器端连接.
     * OioSocketChannel, 同步的客户端 TCP Socket 连接.
     * OioServerSocketChannel, 同步的服务器端 TCP Socket 连接.
     * OioDatagramChannel, 同步的 UDP 连接
     * OioSctpChannel, 同步的 Sctp 服务器端连接.
     * OioSctpServerChannel, 同步的客户端 TCP Socket 连接.
     **/
    public static void main(String[] args) {
        //1.NioEventLoopGroup是执行者
        NioEventLoopGroup group = new NioEventLoopGroup(2);
        System.out.println("NioEventLoopGroup in main :"+group);

        //2.启动器
        Bootstrap bootstrap = new Bootstrap();
        //3.配置启动器
        bootstrap.group(group)
                //udp类型的channel
                .channel(NioDatagramChannel.class)
                .option(ChannelOption.SO_BROADCAST, true)
                .handler(new ChannelInitializer<NioDatagramChannel>(){
                    @Override
                    protected void initChannel(NioDatagramChannel nioDatagramChannel) throws Exception {
                        nioDatagramChannel.pipeline().addLast(new MyUdpDecoder());//3.4在pipeline中加入解码器
                    }
                });
        try {
            //4.bind到指定端口，并返回一个channel，该端口就是监听UDP报文的端口
            Channel channel = bootstrap.bind(RECEIVE_PORT).sync().channel();
            //5.等待channel的close
            channel.closeFuture().sync();
            //6.关闭group
            group.shutdownGracefully();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static class MyUdpDecoder extends MessageToMessageDecoder<DatagramPacket> {
        @Override
        protected void decode(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket, List<Object> list) throws Exception {
            ByteBuf buf = datagramPacket.content();
            String msg = buf.toString(CharsetUtil.UTF_8);
            System.out.println("UdpReciever :"+msg);
        }
    }
}
